'''
这次我们来总结原型模式，什么是原型模式，我们为啥需要它？
原型模式（Prototype Pattern）是用于创建重复的对象，同时又能保证性能。这种类型的设计模式属于创建型模式，
它提供了一种创建对象的最佳方式。
需要大量的基于某个基础原型进行微量修改而得到新原型时使用原型模式最能节省计算机资源（数据和算力资源）
'''
class Foo(object):
    def do(self):
        print("done")

o =  Foo()
"""
try:
    print(o.bar)
except:
    print("no attribute bar found")

setattr(o, "bar", 1)
try:
    print(o.bar)
except:
    print("no attribute bar found")

delattr(o, "bar")
try:
    print(o.bar)
except:
    print("no attribute bar found")
"""
'''
from types import MethodType

def say(self):
    print(self)
o.say = say
print(o.do)
print(o.say)
o.say = MethodType(say, o)
print(o.say)
o.say()
o.do()
'''
'''
上面的例子说明我们可以动态修改类的方法
'''

import copy

# class Prototype:
#     def __init__(self):
#         self._objects = {}
#
#     def register_object(self, name, obj):
#         """Register an object"""
#         self._objects[name] = obj
#
#     def unregister_object(self, name):
#         """Unregister an object"""
#         del self._objects[name]
#
#     def clone(self, name, **attr):
#         """Clone a registered object and update inner attributes dictionary"""
#         obj = copy.deepcopy(self._objects.get(name))
#         obj.__dict__.update(attr)
#         return obj
"""
def Singleton(cls):
    _instance = {}

    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]

    return _singleton

@Singleton
class Leader(object):
    a = {}
    def __init__(self, x=0):
        pass
    def setAddNuber(self,key,value):
        self.a[key] = value
        print(self.a)
    def add(self):
        c = 0
        for key in self.a:
            c = self.a[key] + c
        return c

class A():
    pass

def main():

    propertype = Prototype()
    a = Leader()
    d = Leader()
    a.d = 0
    propertype.register_object(name='a', obj=a)
    b = propertype.clone('a', a=1, b=123)
    c = propertype.clone('a', c=12)
    print(a)
    print(d)
    if a==c:
        print(True)
    else:
        print(False)
    print(b)
    print(c)

if __name__ == '__main__':
    main()
"""
"""
原型设计模式无非就是克隆一个对象。有丝分裂，即细胞分裂的过程，是生物克隆
的一个例子。在这个过程中，细胞核分裂产生两个新的细胞核，其中每个都有与原
来细胞完全相同的染色体和DNA内容。
当我们已有一个对象，并希望创建该对象的一个完整副本时，原型模式就派上用场了，
与单例模式来讲，同样适用，我们可以用原型模式，对单例模式进行补充。就像我们
修改一篇文档，我们会先复制一份，然后在复制版上修改。
"""
"""
python的深浅复制
The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, 
like lists or class instances):
"""
import copy
class A():
    str = 'I am A'
    def __init__(self):
        pass
    def intro(self, str='I am A' ):

        self.str = str
        print(self.str)
# class

# a = A()
# a.intro()
# b = copy.copy(a)
# b.intro()
# print(a, b)
# a.intro('abc')
# print(b.str)
# c = copy.deepcopy(a)
# print(c.str)
# print(a, c)
class B():
    friend = A()
    def __init__(self):
        pass

"""
结果显示，如果你要在两个实例之间共享结果，可以使用deepcopy,
三者（深copy，浅copy，“=”）之间的异同：
（变量分为可变类型和不可变类型，是相对概念,并非绝对概念）
同：
三者都会产生新的对象
不同：
浅copy和原实例公用内部属性
深copy会根据原实例属性的值初始化一个新的属性
=，目前来看python中等于浅copy
"""
will = ["Will", 28, ["python"]]
wills = will
wilber = copy.copy(will)
wilb = copy.deepcopy(will)
# wilber = will
print(id(will[2]))
print(id(wills[2]))
print(id(wilber[2]))
print(id(wilb[2]))
will[0] = "Wilber"
will[2].append("CSS")
print(will)
print(wilber)
print(wilb)



"""
o = 1
a = o
b = copy.deepcopy(a)
o = o+1
print(a)

class A():
    def add(self, y=1, x=1):
        return x+y
a = A()
print(a)
a.add(1,1)
print(a)
"=" 操作符会更改变量（对象ID）
"""
class A():
    c = None
    def add(self, y=1, x=1):
        self.c = x+y
        return self.c
a = A()
print(a.c)
a.add(1,1)
print(a.c)
b = copy.copy(a)
a.add(3,1)
print(a.c)
print(b.c)
# print(b)
"""
Python中对象的赋值都是进行对象引用（内存地址）传递
使用copy.copy()，可以进行对象的浅拷贝，它复制了对象，但对于对象中的元素，依然使用原始的引用.
如果需要复制一个容器对象，以及它里面的所有元素（包含元素的子元素），可以使用copy.deepcopy()进行深拷贝
对于非容器类型（如数字、字符串、和其他'原子'类型的对象）没有被拷贝一说
如果元祖变量只包含原子类型对象，则不能深拷贝，看下面的例子
"""